import sys, os, re, types, time, glob, traceback
import zipfile
import pickle
import ConfigParser
from optparse import OptionParser
from wgcommon import *

class WoWIndex:  
  def __init__(self, options, args):
    self.config = ConfigParser.ConfigParser()
    self.config.read('wow-index.cfg')
    self.path            = self.config.get('Main','dir')
    self.rawPath         = self.config.get('Main','raw')
    self.deliverablePath = self.config.get('Main','deliverable')
    self.queue = []
    self.scan()
    self.force = options.force or False
    self.verbose = options.verbose or True
    
  def scan(self):
    "Builds up a process queue from the raw directory"
    archives = [f for f in os.listdir(self.rawPath)]
    for archive in archives:
      if zipfile.is_zipfile(os.path.join(self.rawPath,archive)):
        if archive not in self.queue:
          self.queue.append(archive)

  def allArchives(self):
    "Process all avalible addons in the raw directory"
    addons = []
    for archive in self.queue:
      processedAddOn = self.oneArchive(os.path.join(self.rawPath,archive))
      if processedAddOn is not None:
        addons.extend(processedAddOn)

    try:
      currentIndex = open('index.dat','r')
      cDict = pickle.load(currentIndex)
      currentIndex.close()
    except:
      cDict = {}

    # Merge
    # -------------------------------------------------------------------------
    # Loop through the current index one time comparing each new addon item
    # by name and version. If the name is the same and the version is greater
    # then place it into the final index, keep the previously indexed mod
    #
    finalAddons = {}
    # Nothing to compare to, use what we have
    if cDict == {}:
      for addon in addons:
        finalAddons[addon.Package] = addon
    else:      
      for nAddon in addons:
        pName = nAddon.Package
        # Possible replacement mod
        if cDict.has_key(nAddon.Package):
          if cDict[pName] < nAddon:
            finalAddons[pName] = nAddon
          else:
            finalAddons[pName] = cDict[pName]
        # New Mod
        else: 
          finalAddons[pName] = nAddon
      # Another loop to add in the previous packages
      for pName in cDict.keys():
        if pName not in finalAddons:
          finalAddons[pName] = cDict[pName]    
    try:
      finalIndex = open('index.dat','w')
      pickle.dump(finalAddons,finalIndex)
      finalIndex.close()
    except:
      print 'Fatal: Could not pickle the index!'
      traceback.print_exc(file=sys.stdout)
      sys.exit(2)
    
  def oneArchive(self,archive):
    "Process a single archive of n number of addons"
    try:
      myArchive = wgZip(archive,'a')
      if myArchive.isProcessed() and self.force is False:
        myArchive.close()
        return None

      if self.verbose:
        print (' Processing Archive: ' + archive.split('/')[-1] + ' ').center(79,'*')
      tocDict = myArchive.getToc()
      addons = []
      regex = re.compile('.*/(.*)\.toc')
      packages = [ "%s" % regex.search(s).groups()[0] for s in tocDict.keys() ]
      for package in packages:
        if self.verbose:
          print ' - Processing ' + package + '... '
        myAddOn = AddOn()
        tocfile = package+'/'+package+'.toc'
        try:
          myAddOn.readTOC(tocDict[tocfile])
        except KeyError:
          match = False
          for key in tocDict.iterkeys():
            tmpKey = package + '/' + package + '.toc'
            if tmpKey.lower() == key.lower():
              match = True
              myAddOn.readTOC(tocDict[key])
          if match is False:
            print " ! Could not find a .toc..."
            
        # Siblings is every package in this archive except for this package
        for sib in packages:
          if sib is not package:
            myAddOn.Siblings.append(sib)
        # Record the time that this package was processed
        myAddOn.IndexTime = time.time()
        # Record the short and friendly package name
        myAddOn.Package = package
        # Pickle these meta attributes into the zip package
        topickle = (myAddOn.Package,myAddOn.IndexTime,myAddOn.Siblings)
        pickled = pickle.dumps(topickle)
        myArchive.writestr(package+'/wg.meta',pickled)
        addons.append( myAddOn )
        # Move the addon to the deliverable folder
        myArchive.spawn(package,self.deliverablePath + '/' + package + '.zip')
        if self.verbose:
          print '   + Sucessful'
      # Don't mark it more than once
      if myArchive.isProcessed() is not True:
        myArchive.markProcessed()
    except zipfile.error:
      print 'Fatal: zipfile error'
      print sys.exc_info()
      traceback.print_exc(file=sys.stdout)
      myArchive.close()
      sys.exit(2)
    except:
      print sys.exc_info()[1]
      myArchive.close()
      sys.exit(2)

    # this array should be glued to a bigger array for final pickling
    return addons
